home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / networking / pgpuam / sources / launchapplication.c < prev    next >
Encoding:
Text File  |  2000-06-23  |  7.9 KB  |  229 lines

  1. // 
  2. // Apple Macintosh Developer Technical Support
  3. //
  4. //  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
  5. //
  6. // You may incorporate this sample code into your applications without
  7. // restriction, though the sample code has been provided "AS IS" and the
  8. // responsibility for its operation is 100% yours.  However, what you are
  9. // not permitted to do is to redistribute the source as "DSC Sample Code"
  10. // after having made changes. If you're going to re-distribute the source,
  11. // we require that you make it clear in the source that the code was
  12. // descended from Apple Sample Code, but that you've made changes.
  13. // 
  14.  
  15. #include <Processes.h>
  16.  
  17.  
  18. #include "LaunchApplication.h"
  19.  
  20. static OSErr FindApplicationProcess (OSType creatorToFind, ProcessSerialNumberPtr processSN);
  21. static OSErr FindApplicationOnDisk (OSType creatorToSearchFor, short startVRefNum, FSSpec* foundApp);
  22.  
  23.  
  24. //------------------------------------------------------------------------------------
  25.  OSErr LaunchApplication (OSType creator)
  26. //------------------------------------------------------------------------------------
  27. {
  28.     ProcessSerialNumber    theAppPSN;
  29.     FSSpec                theAppToLaunch;
  30.     OSErr                err     = noErr;
  31.  
  32.     // Check for already running app
  33.     
  34.     err = FindApplicationProcess(creator , &theAppPSN );
  35.     if(err == noErr)
  36.     {
  37.         err = SetFrontProcess( &theAppPSN );
  38.     } 
  39.     else
  40.     {
  41.         err = FindApplicationOnDisk (creator, 0, &theAppToLaunch);
  42.         if(err == noErr)
  43.         {
  44.             LaunchParamBlockRec    launchPB;
  45.             
  46.             launchPB.launchBlockID            = extendedBlock;
  47.             launchPB.launchEPBLength        = extendedBlockLen;
  48.             launchPB.launchFileFlags        = 0;
  49.             launchPB.launchControlFlags        = launchContinue | launchNoFileFlags;
  50.             launchPB.launchAppSpec            = &theAppToLaunch;
  51.             launchPB.launchAppParameters    = nil;
  52.             
  53.             LaunchApplication( &launchPB );
  54.             
  55.         }    
  56.     }
  57.      
  58.      return err;
  59.     
  60.  
  61.  
  62.  
  63. }
  64.  
  65.  
  66.  
  67.  
  68. //
  69. // This runs through the process list looking for the requested application.  It searches for
  70. // applications of type 'APPL', 'APPC' (control panel apps), 'APPE' (extension apps), and
  71. // 'APPD' (desk accessory apps).  Once the requested application has been found processSN
  72. // will contain the process serial number of the running application that was just found.
  73. //
  74. static OSErr FindApplicationProcess (OSType creatorToFind, ProcessSerialNumberPtr processSN)
  75.  {
  76.     ProcessInfoRec            procInfo;
  77.     FSSpec                    procSpec;
  78.     Str31                    processName;
  79.     OSErr                    err                = noErr;
  80.  
  81.     // Clear out the PSN so we're starting at the beginning of the list.
  82.     processSN->lowLongOfPSN = kNoProcess;
  83.     processSN->highLongOfPSN = kNoProcess;
  84.  
  85.     // Initialize the process information record.
  86.     procInfo.processInfoLength = sizeof (ProcessInfoRec);
  87.     procInfo.processName = &processName[0];
  88.     procInfo.processAppSpec = &procSpec;
  89.  
  90.     // Loop through all the processes until we find the process we want or
  91.     // error out because of some reason (usually, no more processes).
  92.     do {
  93.         err = GetNextProcess (processSN);
  94.         if (err == noErr) {
  95.             err = GetProcessInformation (processSN, &procInfo);
  96.         }
  97.     } while ((procInfo.processSignature != creatorToFind || !(procInfo.processType == 'APPL' ||
  98.              procInfo.processType == 'APPC' || procInfo.processType == 'appe' ||
  99.              procInfo.processType == 'APPD')) && err == noErr);
  100.  
  101.     return (err);
  102. }
  103.  
  104. //
  105. // Finds the requested application on disk searching the desktop database and returns an FSSpec to that app.
  106. // It first searches local disks, then searches remote disks.  Once a possible application has been found
  107. // in the desktop database the application is verified to actually exist because the desktop database is
  108. // often not totally accurate.
  109. //
  110. // If startVRefNum is negative then it will be treated as a VRefNum and the search will start on specified
  111. // volume.  If the value of startVRefNum is 0 or positive then the search starts on the first local disk,
  112. // runs through all local disks, and then searches the first remote volume and runs through all remote
  113. // volumes looking for the requested application.
  114. //
  115. static OSErr FindApplicationOnDisk (OSType creatorToSearchFor, short startVRefNum, FSSpec* foundApp) {
  116.     HVolumeParam            volPB;
  117.     HIOParam                paramPB;
  118.     DTPBRec                    desktopPB;
  119.     GetVolParmsInfoBuffer    volinfo;
  120.     FInfo                    fndrInfo;
  121.     OSErr                    err                = fnfErr;            // default return value
  122.  
  123.     volPB.ioNamePtr = nil;
  124.     paramPB.ioNamePtr = nil;
  125.     paramPB.ioBuffer = (Ptr)&volinfo;
  126.     paramPB.ioReqCount = sizeof (volinfo);
  127.  
  128.     // Try to find the application on the specified disk, if one was specified, first.
  129.     if (startVRefNum < 0) {
  130.         volPB.ioVolIndex = startVRefNum;
  131.         if (PBHGetVInfoSync ((HParmBlkPtr)&volPB) == noErr) {
  132.             // Call PBDTGetPath to find the desktop file on the volume.
  133.             desktopPB.ioCompletion = nil;
  134.             desktopPB.ioNamePtr = nil;
  135.             desktopPB.ioVRefNum = volPB.ioVRefNum;
  136.             desktopPB.ioIndex = 0;        // Find the most recent application.
  137.  
  138.             if (PBDTGetPath (&desktopPB) == noErr) {
  139.                 desktopPB.ioFileCreator = creatorToSearchFor;
  140.                 desktopPB.ioNamePtr = (*foundApp).name;
  141.  
  142.                 if (PBDTGetAPPLSync (&desktopPB) == noErr) {
  143.                     // At this point we think we have found the correct application.
  144.                     (*foundApp).vRefNum = volPB.ioVRefNum;
  145.                     (*foundApp).parID = desktopPB.ioAPPLParID;
  146.  
  147.                     // Verify that this application actually exists.
  148.                     if (FSpGetFInfo (foundApp, &fndrInfo) == noErr && fndrInfo.fdCreator == creatorToSearchFor) {
  149.                         // This application actually exists, we can use it.
  150.                         err = noErr;
  151.                     }
  152.                 }
  153.             }
  154.         }
  155.     }
  156.  
  157.     if (err != noErr) {
  158.         // The application wasn't on the starting disk, so loop over every local volume looking for the application.
  159.         for (volPB.ioVolIndex = 1; PBHGetVInfoSync ((HParmBlkPtr)&volPB) == noErr; volPB.ioVolIndex++) {
  160.             // Call PBHGetVolParms call to ensure the volume is a local volume.
  161.             paramPB.ioVRefNum = volPB.ioVRefNum;
  162.  
  163.             if (PBHGetVolParmsSync ((HParmBlkPtr)¶mPB) == noErr && volinfo.vMServerAdr == 0) {
  164.                 // Call PBDTGetPath to find the desktop file on the volume.
  165.                 desktopPB.ioCompletion = nil;
  166.                 desktopPB.ioNamePtr = nil;
  167.                 desktopPB.ioVRefNum = volPB.ioVRefNum;
  168.                 desktopPB.ioIndex = 0;        // Find the most recent application.
  169.  
  170.                 if (PBDTGetPath (&desktopPB) == noErr) {
  171.                     desktopPB.ioFileCreator = creatorToSearchFor;
  172.                     desktopPB.ioNamePtr = (*foundApp).name;
  173.  
  174.                     if (PBDTGetAPPLSync (&desktopPB) == noErr) {
  175.                         // At this point we think we have found the correct application.
  176.                         (*foundApp).vRefNum = volPB.ioVRefNum;
  177.                         (*foundApp).parID = desktopPB.ioAPPLParID;
  178.  
  179.                         // Verify that this application actually exists.
  180.                         if (FSpGetFInfo (foundApp, &fndrInfo) == noErr && fndrInfo.fdCreator == creatorToSearchFor) {
  181.                             // This application actually exists, we can use it.
  182.                             err = noErr;
  183.                             break;
  184.                         }
  185.                     }
  186.                 }
  187.             }
  188.         }
  189.     }
  190.  
  191.     if (err != noErr) {
  192.         // If we didn't find the application locally, check remote volumes.
  193.  
  194.         // Loop over every local volume looking for the application.
  195.         for (volPB.ioVolIndex = 1; PBHGetVInfoSync ((HParmBlkPtr)&volPB) == noErr; volPB.ioVolIndex++) {
  196.             // Call PBHGetVolParms call to ensure the volume is a remote volume.
  197.             paramPB.ioVRefNum = volPB.ioVRefNum;
  198.  
  199.             if (PBHGetVolParmsSync ((HParmBlkPtr)¶mPB) == noErr && volinfo.vMServerAdr != 0) {
  200.                 // Call PBDTGetPath to find the desktop file on the volume.
  201.                 desktopPB.ioCompletion = nil;
  202.                 desktopPB.ioNamePtr = nil;
  203.                 desktopPB.ioVRefNum = volPB.ioVRefNum;
  204.                 desktopPB.ioIndex = 0;        // Find the most recent application.
  205.  
  206.                 if (PBDTGetPath (&desktopPB) == noErr) {
  207.                     desktopPB.ioFileCreator = creatorToSearchFor;
  208.                     desktopPB.ioNamePtr = (*foundApp).name;
  209.  
  210.                     if (PBDTGetAPPLSync (&desktopPB) == noErr) {
  211.                         // At this point we have found the correct application.
  212.                         (*foundApp).vRefNum = volPB.ioVRefNum;
  213.                         (*foundApp).parID = desktopPB.ioAPPLParID;
  214.  
  215.                         // Verify that this application actually exists.
  216.                         if (FSpGetFInfo (foundApp, &fndrInfo) == noErr && fndrInfo.fdCreator == creatorToSearchFor) {
  217.                             // This application actually exists, we can use it.
  218.                             err = noErr;
  219.                             break;
  220.                         }
  221.                     }
  222.                 }
  223.             }
  224.         }
  225.     }
  226.  
  227.     return err;
  228. }
  229.